#ifndef EDITABLETIMELINEITEM_H
#define EDITABLETIMELINEITEM_H

#include <QObject>
#include <QGraphicsItem>
#include <QPushButton>
#include <QDialog>
#include "global.h"
#include "actioncommands.h"

class GUIActionTimeline;
class RobotActionTrack;

class GUIEditableTimelineItem : public QObject, public QAbstractGraphicsShapeItem{
    Q_OBJECT

public:
    enum BoundaryOption{
        SCROLL_PAST_VISIBLE,
        NO_SCROLL_PAST_VISIBLE
    };

protected:
    int _timestamp, _oldTimestamp;
    bool _dragging;
    GUIActionTimeline* _timeline;
    BoundaryOption _upperBoundOption, _lowerBoundOption;
    QString _contextTip;

    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) = 0;
    virtual QRectF boundingRect() const = 0;

    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);

    virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);

public:
    explicit GUIEditableTimelineItem(int timestamp, GUIActionTimeline* timeline, QGraphicsItem *parent = 0);

    void setContextTip(QString text);
    QString contextTip() const;
    void setUpperMovementBound(BoundaryOption option);
    void setLowerMovementBound(BoundaryOption option);

    void setTimestamp(int msec);
    int timestamp() const;

signals:
    void moved(int newTimestamp, int oldTimestamp);
    void editRequest(int timestamp);
    void deleteRequest(int timestamp);

private slots:
    //Called by the context menu when the user right-clicks and selects to edit this item.
    void onContextEdit();
    //Called by the context menu when the user right-clicks and selects to delete this item.
    void onContextDelete();
};


class EditDialog : public QDialog{
    Q_OBJECT

protected:
    int _timestamp;
    RobotAction* _action;
    QPushButton* _deleteButton;
    QString _contextTip;

    virtual void deleteItem() = 0;
    virtual void saveItem() = 0;

public:
    explicit EditDialog(QWidget *parent = 0);

    void setContextTip(QString tip);
    QString contextTip() const;

    int timestamp() const;

    virtual void loadAction(RobotAction* action);
    virtual void prepDialog(int timestamp);

public slots:
    virtual void accept();

protected slots:
    virtual void onDeleteBtnClicked();

signals:
    void needAction();
};


class GUITimelineTrack : public QObject, public QGraphicsRectItem{
    Q_OBJECT

protected:
    GUIActionTimeline* _timeline;
    RobotActionTrack* _track;
    EditDialog* _editDialog;

    //Query the model and create an EditableTimelineItem from it
    virtual GUIEditableTimelineItem* createItem(int msec) = 0;
    //Virtual function that hooks up the appropriate signals/slots for
    //the items and this timeline
    virtual void addItem(GUIEditableTimelineItem* item);
    virtual void onDeleteConfirmed(GUIEditableTimelineItem* item) = 0;
    virtual void onItemMovedInGUI(int newTimestamp, int oldTimestamp) = 0;

    GUIEditableTimelineItem* findItemAtTime(int msec);

public:
    explicit GUITimelineTrack(RobotActionTrack* track, EditDialog* dialog,
                              GUIActionTimeline* timeline, QGraphicsItem* parent);
public slots:
    //Opens up the edit dialog for editing/creating the item at timestamp.
    void onEditRequest(int timestamp);
    //Opens a confirmation to delete the item, then passes responsibility
    //to delete to the subclass
    void onDeleteRequest(int timestamp);

protected slots:
    //Signals coming from the action model
    virtual void onModelItemCreated(int timestamp);
    virtual void onModelItemDeleted(int timestamp);
    virtual void onModelItemMoved(int newTimestamp, int oldTimestamp);

private slots:
    //Signals coming from the GUI
    void onGUIItemMoved(int newTimestamp, int oldTimestamp);
    void onEditFinished(int result);

signals:
    void editingItem(int timestamp);
    void editingFinished(int timestamp);

};



#endif // EDITABLETIMELINEITEM_H
